home *** CD-ROM | disk | FTP | other *** search
/ Gamers Delight 2 / Gamers Delight 2.iso / Aminet / game / role / pinfocom_3_0.lha / Source / options.c < prev    next >
C/C++ Source or Header  |  1992-10-22  |  11KB  |  405 lines

  1. /* options.c
  2.  *
  3.  *  ``pinfocom'' -- a portable Infocom Inc. data file interpreter.
  4.  *  Copyright (C) 1987-1992  InfoTaskForce
  5.  *
  6.  *  This program is free software; you can redistribute it and/or modify
  7.  *  it under the terms of the GNU General Public License as published by
  8.  *  the Free Software Foundation; either version 2 of the License, or
  9.  *  (at your option) any later version.
  10.  *
  11.  *  This program is distributed in the hope that it will be useful,
  12.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  *  GNU General Public License for more details.
  15.  *
  16.  *  You should have received a copy of the GNU General Public License
  17.  *  along with this program; see the file COPYING.  If not, write to the
  18.  *  Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  19.  */
  20.  
  21. /*
  22.  * $Header: RCS/options.c,v 3.0 1992/10/21 16:56:19 pds Stab $
  23.  */
  24.  
  25. #include <stdio.h>
  26.  
  27. #include "infocom.h"
  28.  
  29. #define Z_CODE_NUM      7
  30.  
  31. static const char *z_code_table[Z_CODE_NUM] =
  32. {
  33.     "Early Interpreter",
  34.     "Early Interpreter",
  35.     "Early Interpreter",
  36.     "Standard Series Interpreter",
  37.     "Plus Series Interpreter",
  38.     "Solid Gold Interactive Fiction",
  39.     "Graphic Interactive Fiction"
  40. };
  41.  
  42. void
  43. check_version()
  44. {
  45.     extern void exit P((int));
  46.     extern header_t data_head;
  47.  
  48.     if (data_head.z_version > 3)
  49.     {
  50.         printf("ERROR: Unsupported Z-code version: %d (%s)\n",
  51.                (int)data_head.z_version,
  52.                (data_head.z_version < Z_CODE_NUM
  53.                 ? z_code_table[data_head.z_version]
  54.                 : "<unknown Z code version>"));
  55.         exit(1);
  56.     }
  57. }
  58.  
  59. static void
  60. verify_game()
  61. {
  62.     extern header_t data_head;
  63.  
  64.     if (data_head.verify_length == 0)
  65.         printf("\nThis game does not support data verification.\n");
  66.     else
  67.     {
  68.         printf("\nVerifying game data... ");
  69.         fflush(stdout);
  70.         if (do_verify())
  71.             printf("successful.\n\n");
  72.         else
  73.             printf("FAILED!\n\n");
  74.     }
  75. }
  76.  
  77. static void
  78. show_header()
  79. {
  80.     extern header_t data_head;
  81.     extern file_t   file_info;
  82.  
  83.     printf("\nInfocom Data File Header\n\nZ-Code version : %d (%s)\n",
  84.            (int)data_head.z_version,
  85.            (data_head.z_version < Z_CODE_NUM
  86.             ? z_code_table[data_head.z_version]
  87.             : "<unknown Z code version>"));
  88.     printf("Release number : %hu\n", data_head.release & 0x7ff);
  89.     printf("Serial number  : %.6s\n\n", data_head.serial_no);
  90.  
  91.     printf("Score/Time     : %s\n", F1_IS_SET(B_USE_TIME) ? "Time" : "Score");
  92.     printf("Tandy License  : %s\n", F1_IS_SET(B_TANDY) ? "On" : "Off");
  93.     printf("Alt. Prompt    : %s\n", F1_IS_SET(B_ALT_PROMPT) ? "On" : "Off");
  94.     printf("Script status  : %s\n", F2_IS_SET(B_SCRIPTING) ? "On" : "Off");
  95.     printf("Has sound      : %s\n\n", F2_IS_SET(B_SOUND) ? "Yes" : "No");
  96.  
  97.     printf("Resident bytes : $%04hx\n", data_head.resident_bytes);
  98.     printf("Save bytes     : $%04hx\n", data_head.save_bytes);
  99.     printf("Common words   : $%04hx\n", data_head.common_word_o);
  100.     printf("Object offset  : $%04hx\n", data_head.object_o);
  101.     printf("Variable offset: $%04hx\n", data_head.variable_o);
  102.     printf("Vocab offset   : $%04hx\n", data_head.vocab_o);
  103.     printf("Start offset   : $%04hx\n", data_head.game_o);
  104.     printf("Alphabet offset: $%04hx\n", data_head.alphabet_o);
  105.     printf("Fkey offset    : $%04hx\n\n", data_head.fkey_o);
  106.  
  107.     printf("Game length    : ");
  108.     if (data_head.verify_length == 0)
  109.         printf("<unknown>\n");
  110.     else
  111.         printf("%ld\n",
  112.                ((long)file_info.pages*BLOCK_SIZE) + (long)file_info.offset);
  113.     printf("Verify length  : $%04hx\n", data_head.verify_length);
  114.     printf("Verify check   : $%04hx\n\n", data_head.verify_checksum);
  115. }
  116.  
  117. static void
  118. wrt_buffer()
  119. {
  120.     extern print_buf_t  *pbf_p;
  121.  
  122.     pbf_p->buf[pbf_p->len] = '\0';
  123.     puts((char *)pbf_p->buf);
  124.     pbf_p->len = 0;
  125. }
  126.  
  127. static int
  128. prt_max_coded A3(int, max, word*, page, word*, offset)
  129. {
  130.     extern int  print_mode;
  131.     extern int  single_mode;
  132.     word        data=0;
  133.  
  134.     print_mode = 0;
  135.     single_mode = 0;
  136.  
  137.     for (; max > 0; --max)
  138.     {
  139.         data = get_word(page, offset);
  140.         decode(data);
  141.     }
  142.  
  143.     return (data & 0x8000);
  144. }
  145.  
  146. static void
  147. show_vocab()
  148. {
  149.     extern print_buf_t  *pbf_p;
  150.     extern word         num_vocab_words;
  151.     extern word         vocab_entry_size;
  152.     extern byte         *wsbf_strt;
  153.     extern byte         *end_of_sentence;
  154.     extern byte         *strt_vocab_table;
  155.     extern byte         *base_ptr;
  156.  
  157.     byte    *ptr;
  158.     word    page;
  159.     word    offset;
  160.     int     count;
  161.     int     words_per_word;
  162.     int     word_width;
  163.     int     wpl;                    /* words per line */
  164.  
  165.     printf("\nInfocom Adventure - Vocabulary List\n\nNumber of words: %hd\n\n",
  166.            num_vocab_words);
  167.  
  168.     fputs("End-of-sentence punctuation: ", stdout);
  169.     for (ptr = wsbf_strt; ptr < end_of_sentence; ++ptr)
  170.     {
  171.         putchar(*ptr);
  172.         putchar(' ');
  173.     }
  174.     putchar('\n');
  175.     putchar('\n');
  176.  
  177.     words_per_word = vocab_entry_size <= 7 ? 2 : 3;
  178.     word_width = (words_per_word * 3) + 2;
  179.     wpl = pbf_p->max / word_width;
  180.  
  181.     ptr = strt_vocab_table;
  182.     pbf_p->buf[0] = ' ';
  183.     pbf_p->len = 1;
  184.  
  185.     for (count = 1; count <= (int)num_vocab_words; ++count)
  186.     {
  187.         int ws;
  188.  
  189.         page = (ptr - base_ptr) / BLOCK_SIZE;
  190.         offset = (ptr - base_ptr) % BLOCK_SIZE;
  191.         ptr += vocab_entry_size;
  192.         ws = pbf_p->len;
  193.  
  194.         /*
  195.          * Some data files have bogus vocabulary words in them which
  196.          * don't have the "end-word" bit set properly, so they can't
  197.          * be used in the game: mark these with "[]"...
  198.          */
  199.         if (!prt_max_coded(words_per_word, &page, &offset))
  200.         {
  201.             pbf_p->buf[ws-1] = '[';
  202.             pbf_p->buf[pbf_p->len++] = ']';
  203.         }
  204.  
  205.         for (; pbf_p->len < ws+word_width; ++pbf_p->len)
  206.             pbf_p->buf[pbf_p->len] = ' ';
  207.  
  208.         if ((count % wpl) == 0)
  209.         {
  210.             wrt_buffer();
  211.             pbf_p->buf[0] = ' ';
  212.             pbf_p->len = 1;
  213.         }
  214.     }
  215.     if (pbf_p->len > 1)
  216.     {
  217.         wrt_buffer();
  218.     }
  219.     putchar('\n');
  220. }
  221.  
  222. static void
  223. show_objects()
  224. {
  225.     extern print_buf_t  *pbf_p;
  226.     extern byte         *base_ptr;
  227.  
  228.     word            page;
  229.     word            offset;
  230.     byte            *obj;
  231.     int             i=1, j;
  232.     int             address;
  233.     int             parent;
  234.     int             sibling;
  235.     int             child;
  236.     int             n_objs;
  237.     int             aw;
  238.  
  239.     puts("\nInfocom Adventure - Object List\n");
  240.  
  241.     pbf_p->len = 0;
  242.     obj = (byte *)obj_addr(i);
  243.  
  244.     n_objs = (objd.is_eobj
  245.               ? Z_TO_WORD(((eobject_t *)obj)->data)
  246.               : Z_TO_WORD(((object_t *)obj)->data));
  247.     n_objs = (n_objs - (obj - base_ptr)) / objd.obj_size;
  248.  
  249.     printf("Number of objects: %d\n\n", n_objs);
  250.  
  251.     aw = 4 + (objd.is_eobj * 2);
  252.     do
  253.     {
  254.         Bool first;
  255.  
  256.         printf("Object %s : ", print_hnum(i));
  257.  
  258.         if (objd.is_eobj)
  259.         {
  260.             address = Z_TO_WORD(((eobject_t *)obj)->data);
  261.             parent  = Z_TO_WORD(((eobject_t *)obj)->parent);
  262.             sibling = Z_TO_WORD(((eobject_t *)obj)->sibling);
  263.             child   = Z_TO_WORD(((eobject_t *)obj)->child);
  264.         }
  265.         else
  266.         {
  267.             address = Z_TO_WORD(((object_t *)obj)->data);
  268.             parent  = ((object_t *)obj)->parent;
  269.             sibling = ((object_t *)obj)->sibling;
  270.             child   = ((object_t *)obj)->child;
  271.         }
  272.  
  273.         page = address / BLOCK_SIZE;
  274.         offset = address % BLOCK_SIZE;
  275.         if (get_byte(&page, &offset) > 0)
  276.             prt_coded(&page, &offset);
  277.         wrt_buffer();
  278.  
  279.         fputs("    -> attributes : (", stdout);
  280.         first = 1;
  281.         for (j = 0; j < aw*8;)
  282.         {
  283.             int k;
  284.  
  285.             for (k = 0x80; k; k>>=1, ++j)
  286.                 if (obj[j/8] & k)
  287.                     printf(first ? (first=0, "%d") : ",%d", j);
  288.         }
  289.  
  290.         printf(")\n    -> parent     : %s\n", print_hnum(parent));
  291.         printf("    -> sibling    : %s\n", print_hnum(sibling));
  292.         printf("    -> child      : %s\n", print_hnum(child));
  293.  
  294.         obj = (byte *)obj_addr(++i);
  295.     }
  296.     while (i <= n_objs);
  297.  
  298.     putchar('\n');
  299. }
  300.  
  301. static void
  302. obtree A2(word, a, int, b)
  303. {
  304.     byte    *obj;
  305.     word    address;
  306.     word    child;
  307.     word    sibling;
  308.     word    page;
  309.     word    offset;
  310.     int     c;
  311.  
  312.     for (c = b*4; c > 0; c--)
  313.         putchar(' ');
  314.  
  315.     printf("%s : ", print_hnum(a));
  316.  
  317.     obj = (byte *)obj_addr(a);
  318.     if (objd.is_eobj)
  319.     {
  320.         address = Z_TO_WORD(((eobject_t *)obj)->data);
  321.         sibling = Z_TO_WORD(((eobject_t *)obj)->sibling);
  322.         child   = Z_TO_WORD(((eobject_t *)obj)->child);
  323.     }
  324.     else
  325.     {
  326.         address = Z_TO_WORD(((object_t *)obj)->data);
  327.         sibling = ((object_t *)obj)->sibling;
  328.         child   = ((object_t *)obj)->child;
  329.     }
  330.  
  331.     page = address / BLOCK_SIZE;
  332.     offset = address % BLOCK_SIZE;
  333.     if (get_byte(&page, &offset) > 0)
  334.         prt_coded(&page, &offset);
  335.     wrt_buffer();
  336.  
  337.     if (child)
  338.         obtree(child, b+1);
  339.     if (sibling)
  340.         obtree(sibling, b);
  341. }
  342.  
  343. static void
  344. show_tree()
  345. {
  346.     extern print_buf_t  *pbf_p;
  347.     extern byte         *base_ptr;
  348.  
  349.     byte            *obj;
  350.     int             i=1;
  351.     int             n_objs;
  352.     int             parent;
  353.  
  354.     puts("\nInfocom Adventure - Object Tree\n");
  355.  
  356.     pbf_p->len = 0;
  357.     obj = (byte *)obj_addr(i);
  358.  
  359.     n_objs = (objd.is_eobj
  360.               ? Z_TO_WORD(((eobject_t *)obj)->data)
  361.               : Z_TO_WORD(((object_t *)obj)->data));
  362.     n_objs = (n_objs - (obj - base_ptr)) / objd.obj_size;
  363.  
  364.     printf("Number of objects: %d\n\n", n_objs);
  365.  
  366.     do
  367.     {
  368.         parent = (objd.is_eobj
  369.                   ? Z_TO_WORD(((eobject_t *)obj)->parent)
  370.                   : ((object_t *)obj)->parent);
  371.  
  372.         if (parent == 0)
  373.         {
  374.             obtree(i, 0);
  375.             putchar('\n');
  376.         }
  377.  
  378.         obj = (byte *)obj_addr(++i);
  379.     }
  380.     while (i <= n_objs);
  381.  
  382.     putchar('\n');
  383. }
  384.  
  385. void
  386. options A5( Bool, verfy,
  387.             Bool, head,
  388.             Bool, objs,
  389.             Bool, vocab,
  390.             Bool, tree )
  391. {
  392.     printf("\nInformation for Infocom data file `%s'\n", gflags.filenm);
  393.  
  394.     if (verfy)
  395.         verify_game();
  396.     if (head)
  397.         show_header();
  398.     if (vocab)
  399.         show_vocab();
  400.     if (objs)
  401.         show_objects();
  402.     if (tree)
  403.         show_tree();
  404. }
  405.